﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
using System.Collections;

namespace SDT.Libraries.Utilities
{
    /// <summary>

    /// This will take anything that implements the ICollection interface and convert

    /// it to a DataSet.

    /// </summary>

    /// <example>

    /// CollectiontoDataSet converter = new CollectionToDataSet<Letters[]>(letters);

    /// DataSet ds = converter.CreateDataSet();

    /// </example>

    /// <typeparam name="T"></typeparam>

    public class CollectionToDataSet<T> where T : System.Collections.ICollection
    {

        T _collection;

        public CollectionToDataSet(T list)
        {

            _collection = list;

        }



        private PropertyInfo[] _propertyCollection = null;

        private PropertyInfo[] PropertyCollection
        {

            get
            {

                if (_propertyCollection == null)
                {

                    _propertyCollection = GetPropertyCollection();

                }

                return _propertyCollection;

            }

        }



        private PropertyInfo[] GetPropertyCollection()
        {

            if (_collection.Count > 0)
            {

                IEnumerator enumerator = _collection.GetEnumerator();

                enumerator.MoveNext();

                return enumerator.Current.GetType().GetProperties();

            }

            return null;

        }



        public DataSet CreateDataSet()
        {

            DataSet ds = new DataSet("GridDataSet");

            ds.Tables.Add(FillDataTable());

            return ds;

        }



        private DataTable FillDataTable()
        {

            IEnumerator enumerator = _collection.GetEnumerator();

            DataTable dt = CreateDataTable();

            while (enumerator.MoveNext())
            {

                dt.Rows.Add(FillDataRow(dt.NewRow(), enumerator.Current));

            }

            return dt;

        }



        private DataRow FillDataRow(DataRow dataRow, object p)
        {

            foreach (PropertyInfo property in PropertyCollection)
            {

                dataRow[property.Name.ToString()] = property.GetValue(p, null);

            }

            return dataRow;

        }



        private DataTable CreateDataTable()
        {

            DataTable dt = new DataTable("GridDataTable");

            foreach (PropertyInfo property in PropertyCollection)
            {

                dt.Columns.Add(property.Name.ToString());

            }

            return dt;

        }

    }
}
